home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-09-02 | 8.5 KB | 225 lines | [TEXT/CCL2] |
- ;;;-*- Mode: Lisp; Package: ccl -*-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;; block-io-mcl.lisp
- ;; low-level block I/O - MCL version.
- ;;
- ;; Copyright © 1992 Apple Computer, Inc. All rights reserved.
- ;; Permission is given to use, copy, and modify this software provided
- ;; that this copyright notice is attached to all derivative works.
- ;; This software is provided "as is". Apple makes no warranty or
- ;; representation, either express or implied, with respect to this software,
- ;; its quality, accuracy, merchantability, or fitness for a particular
- ;; purpose.
- ;;
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;; Modification history
- ;;
- ;; ------------ 0.5
- ;; 03/05/92 bill New file
- ;;
-
- (in-package :ccl)
-
- (export '(stream-read-bytes stream-write-bytes set-minimum-file-length))
-
- (provide :block-io)
-
- ;; (stream-read-bytes stream address vector offset length)
- ;; read length bytes into vector at offset from stream at address.
- ;;
- ;; (stream-write-bytes stream address vector offset length)
- ;; write length bytes from stream at address into vector at offset.
- ;; Extend the length of the file if necessary.
- ;;
- ;; (set-minimum-file-length stream length)
- ;; Set the file length of stream to >= length.
- ;;
- ;; This implementation only supports vectors of type
- ;; (array (unsigned-byte 8)), (array (signed-byte 8)), or simple-string
-
- (eval-when (eval compile)
- (require 'lapmacros)
- (require 'lispequ)
-
- ;structure of fblock
- ;from "ccl:level-1;l1-sysio.lisp"
-
- (let ((*warn-if-redefine* nil))
-
- (def-accessors (fblock) %svref
- nil ; 'fblock
- fblock.pb ; a parameter block; nil if closed.
- fblock.lastchar ; untyi char or nil
- fblock.dirty ; non-nil when dirty
- fblock.buffer ; macptr to buffer; nil when closed
- fblock.bufvec ; buffer vector; nil when closed
- fblock.bufsize ; size (in 8-bit bytes) of buffer
- fblock.bufidx ; index of next element to read/write
- fblock.bufcount ; # of elements in buffer
- fblock.filepos ; 8-bit position at last read/write
- fblock.fileeof ; file's logical eof.
- fblock.stream ; backptr to file stream
- fblock.element-type ; typespec
- fblock.nbits-per-element ; # of bits per element
- fblock.elements-per-buffer ; 512 or whatever
- fblock.minval ; minimum value of element type or nil: < 0
- fblock.maxval ; maximum value or nil
- fblock.element-bit-offset ; for non-arefable n-bit elements
- )
-
- ) ; end of let
-
- ) ; end of eval-when
-
- ; Read length bytes into array at offset from stream at address.
- ; Array must be a simple (byte 8) array.
- ; stream must be an input stream for 8 bit elements.
- (defmethod stream-read-bytes ((stream input-file-stream)
- address array offset length)
- (%fread-bytes (slot-value stream 'fblock)
- (require-type address 'fixnum)
- array
- (require-type offset 'fixnum)
- (require-type length 'fixnum)))
-
- (defun %fread-bytes (fblock address array offset length)
- (declare (fixnum address offset length))
- (unless (eql 8 (fblock.nbits-per-element fblock))
- (error "%fread-bytes only implemented for 8-bit bytes"))
- (unless (>= (length array) (the fixnum (+ offset length)))
- (error "array too small"))
- (when (lap-inline (array)
- (move.l arg_z atemp0)
- (movereg arg_z acc)
- (if# (and (ne (dtagp arg_z $t_vector))
- (or (eq (progn (move.b (atemp0 $v_subtype) da)
- (cmp.b ($ $v_ubytev) da)))
- (eq (cmp.b ($ $v_sbytev) da))
- (eq (cmp.b ($ $v_sstr) da))))
- (move.l nilreg acc)))
- (%badarg array '(or (array (signed-byte 8))
- (array (unsigned-byte 8))
- simple-string)))
- (let ((max-length (- (%fsize fblock) address)))
- (declare (fixnum max-length))
- (if (< max-length length) (setq length max-length))
- (if (< length 0) (setq length 0)))
- (let ((bytes length)
- (bufvec (fblock.bufvec fblock)))
- (declare (fixnum bytes))
- (loop
- (when (<= length 0) (return bytes))
- (%fpos fblock address)
- (let* ((vec-index (- address (the fixnum (fblock.filepos fblock))))
- (vec-left (- (the fixnum (fblock.bufcount fblock)) vec-index)))
- (declare (fixnum vec-index vec-left))
- ; (print-db vec-index vec-left)
- (if (> vec-left length) (setq vec-left length))
- (lap-inline ()
- (:variable bufvec array offset vec-index vec-left)
- (move.l (varg bufvec) atemp0)
- (move.l (varg vec-index) acc)
- (getint acc)
- (lea (atemp0 acc $v_data) atemp0)
- (move.l (varg array) atemp1)
- (move.l (varg offset) acc)
- (getint acc)
- (lea (atemp1 acc $v_data) atemp1)
- (move.l (varg vec-left) acc)
- (getint acc)
- (dbfloop acc (move.b atemp0@+ atemp1@+)))
- (incf address vec-left)
- (decf length vec-left)))))
-
- ; same, but other direction
- (defmethod stream-write-bytes ((stream output-file-stream)
- address array offset length)
- (%fwrite-bytes (slot-value stream 'fblock)
- (require-type address 'fixnum)
- array
- (require-type offset 'fixnum)
- (require-type length 'fixnum)))
-
- (defun %fwrite-bytes (fblock address array offset length)
- (declare (fixnum address offset length))
- (unless (eql 8 (fblock.nbits-per-element fblock))
- (error "%fwrite-bytes only implemented for 8-bit bytes"))
- (unless (>= (length array) (the fixnum (+ offset length)))
- (error "array too small"))
- (when (lap-inline (array)
- (move.l arg_z atemp0)
- (movereg arg_z acc)
- (if# (and (ne (dtagp arg_z $t_vector))
- (or (eq (progn (move.b (atemp0 $v_subtype) da)
- (cmp.b ($ $v_ubytev) da)))
- (eq (cmp.b ($ $v_sbytev) da))
- (eq (cmp.b ($ $v_sstr) da))))
- (move.l nilreg acc)))
- (%badarg array '(or (array (signed-byte 8))
- (array (unsigned-byte 8))
- simple-string)))
- (let ((min-size (+ address length)))
- (declare (fixnum min-size))
- (when (> min-size (%fsize fblock))
- (%fsize fblock min-size)))
- (let ((bytes length)
- (bufvec (fblock.bufvec fblock)))
- (declare (fixnum bytes))
- (loop
- (when (<= length 0) (return bytes))
- (%fpos fblock address)
- (let* ((vec-index (- address (the fixnum (fblock.filepos fblock))))
- (vec-left (- (the fixnum (fblock.elements-per-buffer fblock))
- vec-index)))
- (declare (fixnum vec-index vec-left))
- (if (> vec-left length) (setq vec-left length))
- (lap-inline ()
- (:variable bufvec array offset vec-index vec-left)
- (move.l (varg bufvec) atemp0)
- (move.l (varg vec-index) acc)
- (getint acc)
- (lea (atemp0 acc $v_data) atemp0)
- (move.l (varg array) atemp1)
- (move.l (varg offset) acc)
- (getint acc)
- (lea (atemp1 acc $v_data) atemp1)
- (move.l (varg vec-left) acc)
- (getint acc)
- (dbfloop acc (move.b atemp1@+ atemp0@+)))
- (let ((index (+ vec-index vec-left))
- (bufcount (fblock.bufcount fblock)))
- (declare (fixnum index bufcount))
- (if (> index bufcount)
- (setf (fblock.bufcount fblock) index))
- (setf (fblock.bufidx fblock) index
- (fblock.dirty fblock) t))
- (incf address vec-left)
- (decf length vec-left)))))
-
- (defun set-minimum-file-length (stream length)
- (file-length stream length))
-
- #|
- (setq s (open "temp.lisp" :direction :io :if-exists :overwrite))
-
- (defun r (address length)
- (declare (special s))
- (let ((v (make-string length)))
- (let ((real-length (stream-read-bytes s address v 0 length)))
- (if (eql length real-length)
- (values v length)
- (let ((res (make-string real-length)))
- (dotimes (i real-length)
- (setf (aref res i) (aref v i)))
- (values res real-length))))))
-
- (defun w (string address &optional
- (offset 0) (length (- (length string) offset)))
- (declare (special s))
- (stream-write-bytes s address string offset length))
-
- |#